﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
using Microsoft.Web.Media.SmoothStreaming;
using System.Diagnostics;
using System.Windows.Threading;

namespace LiveStream
{
	public class Timeline : Slider, INativePlayerElement
	{
		public bool IsScrubbing { get; private set; }
		public Thumb Thumb { get; private set; }
		public Panel Panel { get; private set; }
		public Border Border { get; private set; }
		public NativePlayer Player { get; private set; }
		private bool Updating { get; set; }
		private TimeSpan _desiredPosition;
        private bool _wasPlaying=false;

		public override void OnApplyTemplate()
		{
			base.OnApplyTemplate();
			Thumb = GetTemplateChild("HorizontalThumb") as Thumb;
			Panel = GetTemplateChild("HorizontalTemplate") as Panel;

			Thumb.DragStarted += new DragStartedEventHandler(Thumb_DragStarted);
			Thumb.DragCompleted += new DragCompletedEventHandler(Thumb_DragCompleted);
			Thumb.DragDelta += new DragDeltaEventHandler(Thumb_DragDelta);

			Thumb.IsHitTestVisible = true;
			Thumb.MouseLeftButtonDown += new MouseButtonEventHandler(Thumb_MouseLeftButtonDown);

			ValueChanged += new RoutedPropertyChangedEventHandler<double>(Timeline_ValueChanged);
			Player.PositionChanged += new EventHandler<EventArgs<TimeSpan>>(Position_Changed);
			Player.EndPositionChanged += new EventHandler<EventArgs<TimeSpan>>(EndPosition_Changed);
			Player.MediaOpened += new RoutedEventHandler(player_MediaOpened);
			Player.CurrentStateChanged += new RoutedEventHandler(Player_CurrentStateChanged);
			Player.Unloaded += new RoutedEventHandler(Player_Unloaded);
			Player.SeekCompleted += new EventHandler<SeekCompletedEventArgs>(Player_SeekCompleted);
		}

		void Player_SeekCompleted(object sender, SeekCompletedEventArgs e)
		{
			Debug.WriteLine("Seek Completed: {0}, {1}", e.ActualSeekPosition, e.Success);
            if (_desiredPosition != TimeSpan.MinValue)
                if (Math.Abs((_desiredPosition - Player.Position).TotalMilliseconds) > 200)
                {
                    //We aren't where we want to be
                    //Seek again
                    Player.Position = _desiredPosition;
                }
                else
                    _desiredPosition = TimeSpan.MinValue;
		}

		public void Initialize(NativePlayer player)
		{
			Player = player;
		}

		void Player_Unloaded(object sender, RoutedEventArgs e)
		{
			SetState(SmoothStreamingMediaElementState.Closed);
		}

		void Player_CurrentStateChanged(object sender, RoutedEventArgs e)
		{
			var player = sender as NativePlayer;
			SetState(player.CurrentState);
		}

		private void SetState(SmoothStreamingMediaElementState state)
		{
			switch (state)
			{
				case SmoothStreamingMediaElementState.Buffering:
				case SmoothStreamingMediaElementState.Paused:
				case SmoothStreamingMediaElementState.Playing:
					IsEnabled = true;
					break;
				default:
					IsEnabled = false;
					break;
			}
		}


		void player_MediaOpened(object sender, RoutedEventArgs e)
		{
			var length = (sender as NativePlayer).EndPosition.TotalMilliseconds;
			Resize(length);
		}

		private void Resize(double length)
		{
			Maximum = length;
			SmallChange = 100;
			LargeChange = length / 10;
		}

		void Timeline_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			if (!Updating)  //Position change occurred anywhere except from playback progressing
			{
				Debug.WriteLine("Value Changed: {0}, {1}", e.NewValue, Player.CanSeek);

				_desiredPosition = TimeSpan.FromMilliseconds(Value);
                Player.Position = _desiredPosition;
			}
		}

		public void Position_Changed(object sender, EventArgs<TimeSpan> e)
		{
			if (!IsScrubbing)
			{
				Updating = true;

                Value = e.Value.TotalMilliseconds;

				Updating = false;
			}
		}

		public void EndPosition_Changed(object sender, EventArgs<TimeSpan> e)
		{
			Resize(e.Value.TotalMilliseconds);
		}

		void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
		{
			Debug.WriteLine("Drag Delta: {0}", e.HorizontalChange);
			IsScrubbing = true;
		}

		void Thumb_DragStarted(object sender, DragStartedEventArgs e)
		{
			IsScrubbing = true;
            _wasPlaying = (Player.CurrentState == SmoothStreamingMediaElementState.Playing);
			Player.Pause();
		}

		void Thumb_DragCompleted(object sender, DragCompletedEventArgs e)
		{
			IsScrubbing = false;

			if(_wasPlaying)
				Player.Play();
		}

		void Thumb_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
		{
			IsScrubbing = true;
		}
	}
}
